package org.lib.mysqlhello.common;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Aspect
@Component
public class WebLogAspect {

	@Autowired
	private HttpServletRequest req;
	
//	@Autowired
//	private HttpServletResponse resp;

	@Pointcut(value="execution(public * org.lib.mysqlhello.user.controller..*.*(..))")
	private void ptUserController() {
	}
	
	/**
	 * Before
	 * @author ben
	 * @date 2021-08-22 11:32:28 CST
	 * @param joinPoint
	 */
//	@Before(value="execution(public * org.lib.mysqlhello.user.controller..*.*(..))")
	@Before(value="ptUserController()")
	public void logBeforeUserController(JoinPoint joinPoint) {
		log.info("请求before:{}", req.getRequestURI());
	}
	
	/**
	 * Around
	 * @author ben
	 * @date 2021-08-22 11:32:21 CST
	 * @param pjp
	 * @return
	 * @throws Throwable
	 */
//	@Around(value="execution(public * org.lib.mysqlhello.user.controller..*.*(..))")
	@Around(value="ptUserController()")
	public Object logAroundUserController(ProceedingJoinPoint pjp) throws Throwable {
		try {
			// 在 @Before 之后执行
			log.info("请求around: {}", req.getRequestURI());
			return pjp.proceed();
		} catch (Exception e) {
			log.error("请求around发生异常：{}, e={}", req.getRequestURI(), e.getMessage());
			throw e;
			
			// return后，全局异常处理无效了！
//			return ResultVO.getFailed(500, "发生异常-@Aspect-Around", e.getMessage());
		} finally {
			// 在 @After 之后执行
			log.info("请求around-finally: {}", req.getRequestURI());
		}
	}
	
	/**
	 * AfterReturning
	 * @author ben
	 * @date 2021-08-22 11:32:15 CST
	 */
//	@AfterReturning(value="execution(public * org.lib.mysqlhello.user.controller..*.*(..))")
//	@AfterReturning(value="ptUserController()")
	@AfterReturning(pointcut="ptUserController()")
	public void logAfterReturningUserController() {
		log.info("请求afterReturning:{}", req.getRequestURI());
	}

	/**
	 * AfterThrowing 1-不抛出异常，没有throwing属性
	 * @author ben
	 * @date 2021-08-22 11:30:33 CST
	 */
//	@AfterThrowing(value="execution(public * org.lib.mysqlhello.user.controller..*.*(..))")
//	@AfterThrowing(value="ptUserController()")
	@AfterThrowing(pointcut = "ptUserController()")
	public void logAfterThrowingUserController() {
		log.info("请求afterThrowing:{}, nothing...", req.getRequestURI());
	}
	
	/**
	 * AfterThrowing 2-抛出异常，必须有throwing属性
	 * @author ben
	 * @date 2021-08-22 11:31:02 CST
	 * @param ex
	 */
//	@AfterThrowing(value="execution(public * org.lib.mysqlhello.user.controller..*.*(..))", throwing = "ex")
//	@AfterThrowing(value="ptUserController()", throwing = "ex")
	@AfterThrowing(pointcut = "ptUserController()", throwing = "ex")
	public void logAfterThrowingUserController(Exception ex) {
		log.info("请求afterThrowing:{}, ex.msg={}", req.getRequestURI(), ex.getMessage());
	}
	
	/**
	 * After
	 * @author ben
	 * @date 2021-08-22 11:31:59 CST
	 */
//	@After(value="execution(public * org.lib.mysqlhello.user.controller..*.*(..))")
	@After(value="ptUserController()")
	public void logAfterUserController() {
		log.info("请求after:{}", req.getRequestURI());
	}
	
}
